﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LinqToTwitter.Common;
using LitJson;

namespace LinqToTwitter
{
    public class UserStreamParser
    {
        private UserStreamParser(IQueryable<Streaming> userStream)
        {
            userStream.StartAsync(c => Task.Run(() => this.ParseContent(c)))
                .ContinueWith(t => this.connections = t.Result);
        }

        public static UserStreamParser Create(IQueryable<Streaming> userStream)
        {
            return new UserStreamParser(userStream);
        }

        private List<Streaming> connections;

        public void Close()
        {
            if (connections != null)
                foreach (var s in connections)
                    s.CloseStream();
        }

        private void ParseContent(StreamContent content)
        {
            if (string.IsNullOrEmpty(content.Content)) return;

            var parsed = JsonMapper.ToObject(content.Content);

            if (parsed.GetValue<JsonData>("text") != null)
            {
                if (this.ReceivedStatus != null)
                    this.ReceivedStatus(this, new UserStreamReceivedStatusEventArgs(content.Content));
                return;
            }

            if (parsed.GetValue<JsonData>("direct_message") != null)
            {
                if (this.ReceivedDirectMessage != null)
                    this.ReceivedDirectMessage(this, new UserStreamReceivedDirectMessageEventArgs(content.Content));
                return;
            }

            var delete = parsed.GetValue<JsonData>("delete");
            if (delete != null)
            {
                if (delete.GetValue<JsonData>("status") != null)
                {
                    if (this.ReceivedDeletedStatus != null)
                        this.ReceivedDeletedStatus(this, new UserStreamReceivedDeletedEventArgs(content.Content));
                }
                else
                {
                    if (this.ReceivedDeletedDirectMessage != null)
                        this.ReceivedDeletedDirectMessage(this, new UserStreamReceivedDeletedEventArgs(content.Content));
                }
                return;
            }

            if (parsed.GetValue<JsonData>("event") != null)
            {
                if (this.ReceivedEvent != null)
                    this.ReceivedEvent(this, new UserStreamReceivedEventEventArgs(content.Content));
                return;
            }

            if (parsed.GetValue<JsonData>("friends") != null)
            {
                if (this.ReceivedFriends != null)
                    this.ReceivedFriends(this, new UserStreamReceivedFriendsEventArgs(content.Content));
                return;
            }

            if (this.ReceivedUnknownData != null)
            {
                this.ReceivedUnknownData(this, new UserStreamReceivedDataEventArgs(content.Content));
            }
        }

        public event EventHandler<UserStreamReceivedStatusEventArgs> ReceivedStatus;
        public event EventHandler<UserStreamReceivedDirectMessageEventArgs> ReceivedDirectMessage;
        public event EventHandler<UserStreamReceivedDeletedEventArgs> ReceivedDeletedStatus;
        public event EventHandler<UserStreamReceivedDeletedEventArgs> ReceivedDeletedDirectMessage;
        public event EventHandler<UserStreamReceivedEventEventArgs> ReceivedEvent;
        public event EventHandler<UserStreamReceivedFriendsEventArgs> ReceivedFriends;
        public event EventHandler<UserStreamReceivedDataEventArgs> ReceivedUnknownData;
    }
}
